// Deep Earth is a community project available under the Microsoft Public License (Ms-PL)
// Code is provided as is and with no warranty - Use at your own risk
// View the project and the latest code at http://DeepEarth.codeplex.com/

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using DeepEarth.Client.MapControl;

namespace DeepEarth.Client.Controls.DEMap
{
    [TemplatePart(Name = PART_scaleTextBlock, Type = typeof(TextBlock))]
    [TemplateVisualState(Name = VSM_Normal, GroupName = VSM_CommonStates)]
    [TemplateVisualState(Name = VSM_MouseOver, GroupName = VSM_CommonStates)]
    public class ScalePanel : Control, IMapControl<Map>
    {
        private const string PART_scaleTextBlock = "PART_scaleTextBlock";
        private const string VSM_CommonStates = "CommonStates";
        private const string VSM_MouseOver = "MouseOver";
        private const string VSM_Normal = "Normal";
        private bool _isMouseOver;

        private Map _mapInstance;

        private string _mapName;
        private TextBlock _scaleTextBlock;

        public ScalePanel()
        {
            DefaultStyleKey = typeof(ScalePanel);

            if (!DesignerProperties.IsInDesignTool)
            {
                IsEnabled = false;
                Loaded += ScalePanel_Loaded;
            }
        }

        #region IMapControl<Map> Members

        public string MapName
        {
            get { return _mapName; }
            set
            {
                _mapName = value;
                SetMapInstance(MapName);
            }
        }

        public Map MapInstance
        {
            get { return _mapInstance; }
            set
            {
                if (_mapInstance != null)
                {
                    _mapInstance.Events.MapViewChanged -= MapViewChange;
                }
                _mapInstance = value;
                if (_mapInstance != null)
                {
                    _mapInstance.Events.MapViewChanged += MapViewChange;
                }
            }
        }

        public void Dispose()
        {
            MapInstance = null;
            MouseEnter -= MapMouseEnter;
            MouseLeave -= MapMouseLeave;
        }

        #endregion

        private void ScalePanel_Loaded(object sender, RoutedEventArgs e)
        {
            SetMapInstance(MapName);
            MouseEnter += MapMouseEnter;
            MouseLeave += MapMouseLeave;
            GoToState(true);
        }


        private void SetMapInstance(string mapname)
        {
            MapInstance = Utilities.FindVisualChildByName<Map>(Application.Current.RootVisual, mapname);
        }

        public override void OnApplyTemplate()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                base.OnApplyTemplate();
                _scaleTextBlock = (TextBlock)GetTemplateChild(PART_scaleTextBlock);
                IsEnabled = true;

                //set inital values
                SetMapScale();
            }
        }

        private void MapViewChange(object sender, EventArgs e)
        {
            if (IsEnabled)
            {
                SetMapScale();
            }
        }

        private void MapMouseLeave(object sender, MouseEventArgs e)
        {
            _isMouseOver = false;
            if (IsEnabled)
            {
                GoToState(true);
            }
        }

        private void MapMouseEnter(object sender, MouseEventArgs e)
        {
            _isMouseOver = true;
            if (IsEnabled)
            {
                GoToState(true);
            }
        }

        private void SetMapScale()
        {
            _scaleTextBlock.Text = "Scale 1:"
                + Math.Round(Utilities.GetScaleAtZoomLevel(MapInstance.GeoCenter.Latitude, MapInstance.ZoomLevel), 0);
        }

        private void GoToState(bool useTransitions)
        {
            VisualStateManager.GoToState(this, _isMouseOver ? VSM_MouseOver : VSM_Normal, useTransitions);
        }
    }
}